#include "Pattern.h"

#include "PKB.h"

Pattern::Pattern()
{
}

Pattern::~Pattern()
{
}

vector<vector<INTEGER>> Pattern::evaluateWhileIfControlVariable(vector<INTEGER> list, string variable)
{
	vector<INTEGER> result;
	vector<vector<INTEGER>> result_structured;
	string targetString;
	int temp=-1;
	for (int i=0;i<list.size();i++)
	{
		temp = list[i];
		//get varName that the control variable of the while statement and see if it matches what the pql clause specifies
		if (matcher.matchExact(variable,PKB::ast.GetValue(PKB::ast.GetChild(PKB::ast.GetNodeByStatementNumber(temp),0))))
		{
			result.push_back(temp);
		}
	}
	result_structured.push_back(result);
	return result_structured;
}

vector<vector<INTEGER>> Pattern::evaluateWhileIfControlVariableV2(vector<INTEGER> list, vector<int> listOfVariables, int leftFilterSwitch)
{
	vector<INTEGER> result;
	vector<vector<INTEGER>> result_structured;
	string targetString;
	int temp=-1;
	sort(listOfVariables.begin(),listOfVariables.end());
	for (int i=0;i<list.size();i++)
	{
		temp = list[i];
		//get varName that the control variable of the while statement and see if it matches what the pql clause specifies
		//if (matcher.matchExact(variable,PKB::ast.GetValue(PKB::ast.GetChild(PKB::ast.GetNodeByStatementNumber(temp),0))))
		//{
		//	result.push_back(temp);
		//}
		if (leftFilterSwitch==this->LEFT_UNDERSCORE||binary_search(listOfVariables.begin(),listOfVariables.end(),PKB::varTable.GetVarIndex(PKB::ast.GetValue(PKB::ast.GetChild(PKB::ast.GetNodeByStatementNumber(temp),0)))))
		{
			result.push_back(temp);
		}
	}
	result_structured.push_back(result);
	return result_structured;
}

vector<vector<INTEGER>> Pattern::evaluateAssign(vector<INTEGER> list, string leftFilterCondition, int leftFilterSwitch,	string expressionInfix, int rightFilterSwitch)
{
	
	vector<INTEGER> result;
	vector<vector<INTEGER>> result_structured;
	string targetString;
	INTEGER temp=-1;
	StringTokenizer tokenizer(expressionInfix);
	string expressionPostfix = utilities.convertInfixPostfix(tokenizer);
	vector<int> bmpComputeVector = utilities.computeBmpLast(expressionPostfix);
	for (int i=0;i<list.size();i++)
	{
		bool valid = true;
		temp = list[i];

		TNode* assignNode = PKB::ast.GetNodeByStatementNumber(temp);
		/*
		if (assignNode==NULL)
			cout << temp << " " << "null" << endl;
		else
			cout << temp << " " << "not null" << endl;
			*/
		if (leftFilterSwitch==this->LEFT_VARIABLE)
		{
			valid = valid && 
				matcher.matchExact(leftFilterCondition,PKB::ast.GetValue(PKB::ast.GetChild(assignNode,0)));
		}
		if (valid&&(rightFilterSwitch==this->RIGHT_EXACT_EXPRESSION))
		{
			valid = valid &&
				matcher.matchExact(expressionPostfix,PKB::ast.GetValue(assignNode));
		}
		else if (valid&&(rightFilterSwitch==this->RIGHT_SUB_EXPRESSION))
		{
			valid = valid &&
				(utilities.bmpSearch(PKB::ast.GetValue(assignNode),expressionPostfix,bmpComputeVector) > -1);
		}
		if (valid)
		{
			result.push_back(temp);
		}

	}
	result_structured.push_back(result);
	return result_structured;
}

vector<vector<INTEGER>> Pattern::evaluateAssignV2(vector<INTEGER> list, vector<int> listOfVariables, int leftFilterSwitch,	string expressionInfix, int rightFilterSwitch)
{
	
	vector<INTEGER> result;
	vector<vector<INTEGER>> result_structured;
	string targetString;
	int temp=-1;
	StringTokenizer tokenizer(expressionInfix);
	string expressionPostfix = utilities.convertInfixPostfix(tokenizer);
	vector<int> bmpComputeVector = utilities.computeBmpLast(expressionPostfix);
	sort(listOfVariables.begin(),listOfVariables.end());
	for (int i=0;i<list.size();i++)
	{
		bool valid = true;
		temp = list[i];
		TNode* assignNode = PKB::ast.GetNodeByStatementNumber(temp);
		if (leftFilterSwitch==this->LEFT_VARIABLE)
		{
			valid = valid &&
				binary_search(listOfVariables.begin(),listOfVariables.end(),
				PKB::varTable.GetVarIndex(PKB::ast.GetValue(PKB::ast.GetChild(PKB::ast.GetNodeByStatementNumber(temp),0))));
				//matcher.matchExact(leftFilterCondition,PKB::ast.GetValue(PKB::ast.GetChild(assignNode,0)));
		}
		if (valid&&(rightFilterSwitch==this->RIGHT_EXACT_EXPRESSION))
		{
			valid = valid &&
				matcher.matchExact(expressionPostfix,PKB::ast.GetValue(assignNode));
		}
		else if (valid&&(rightFilterSwitch==this->RIGHT_SUB_EXPRESSION))
		{
			valid = valid &&
				(utilities.bmpSearch(PKB::ast.GetValue(assignNode),expressionPostfix,bmpComputeVector) > -1);
		}
		if (valid)
		{
			result.push_back(temp);
		}

	}
	result_structured.push_back(result);
	return result_structured;
}